package com.ikingtech.platform.service.system.role.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.enums.system.role.DataScopeTypeEnum;
import com.ikingtech.framework.sdk.user.api.UserRoleApi;
import com.ikingtech.framework.sdk.user.model.UserRoleDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.platform.service.system.role.entity.RoleDataScopeDO;
import com.ikingtech.platform.service.system.role.entity.RoleMenuDO;
import com.ikingtech.platform.service.system.role.service.repository.RoleDataScopeRepository;
import com.ikingtech.platform.service.system.role.service.repository.RoleMenuRepository;
import com.ikingtech.platform.service.system.role.service.repository.RoleRepository;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
public class UserRoleService implements UserRoleApi {

    private final RoleRepository repo;

    private final RoleDataScopeRepository roleDataScopeRepo;

    private final RoleMenuRepository roleMenuRepo;

    /**
     * 根据角色ID列表加载用户角色DTO列表
     * @param roleIds 角色ID列表
     * @return 用户角色DTO列表
     */
    @Override
    public List<UserRoleDTO> loadByIds(List<String> roleIds) {
        if (Tools.Coll.isBlank(roleIds)) {
            return new ArrayList<>();
        }
        // 根据角色ID列表查询角色数据范围实体列表
        List<RoleDataScopeDO> roleDataScopeEntities = this.roleDataScopeRepo.list(Wrappers.<RoleDataScopeDO>lambdaQuery()
                .in(RoleDataScopeDO::getRoleId, roleIds));
        // 将角色数据范围实体列表转换为角色ID和数据范围编码的映射
        Map<String, List<String>> dataScopeCodeMap = Tools.Coll.convertGroup(roleDataScopeEntities, RoleDataScopeDO::getRoleId, RoleDataScopeDO::getDataScopeCode);
        // 将用户角色实体列表转换为用户角色DTO列表
        return Tools.Coll.convertList(this.repo.listByIds(roleIds), entity -> {
            UserRoleDTO userRole = new UserRoleDTO();
            userRole.setRoleId(entity.getId());
            userRole.setRoleName(entity.getName());
            userRole.setRoleDataScopeType(DataScopeTypeEnum.valueOf(entity.getDataScopeType()));
            userRole.setRoleDataScopeCodes(dataScopeCodeMap.get(entity.getId()));
            userRole.setTenantCode(entity.getTenantCode());
            return userRole;
        });
    }

    /**
     * 根据菜单ID列表和租户代码加载角色ID列表
     *
     * @param menuIds 菜单ID列表
     * @param tenantCode 租户代码
     * @return 角色ID列表
     */
    @Override
    public List<String> loadIdByMenuIds(List<String> menuIds, String tenantCode) {
        if (Tools.Coll.isBlank(menuIds)) {
            return new ArrayList<>();
        }
        // 使用lambdaQuery方法构建查询条件
        return this.roleMenuRepo.listObjs(Wrappers.<RoleMenuDO>lambdaQuery()
                .select(RoleMenuDO::getRoleId)
                .in(RoleMenuDO::getMenuId, menuIds)
                .eq(RoleMenuDO::getTenantCode, tenantCode));
    }

    /**
     * 根据菜单ID和租户代码加载角色菜单ID列表
     *
     * @param menuId 菜单ID
     * @param tenantCode 租户代码
     * @return 角色菜单ID列表
     */
    @Override
    public List<String> loadIdByMenuId(String menuId, String tenantCode) {
        return this.roleMenuRepo.listObjs(Wrappers.<RoleMenuDO>lambdaQuery()
                .select(RoleMenuDO::getRoleId)
                .eq(RoleMenuDO::getMenuId, menuId)
                .eq(RoleMenuDO::getTenantCode, tenantCode));
    }
}
